package com.scalar.chiptrack.utils;

import org.apache.struts.util.LabelValueBean;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.ArrayList;
import java.text.SimpleDateFormat;


public final class DateUtil
 {
    /**     * No need for an instance     */
    private DateUtil() {
    }

    /**
     * elapsed days based on current time
     *
     * @param date Date
     *
     * @return int number of days    */

    public static int getElapsedDays(Date date) {
        return elapsed(date, Calendar.DATE);
    }

    /**
     * Elapsed days based on two Date objects
     *
     * @param d1 Date
     * @param d2 Date
     *
     * @return int number of days    */
    public static int getElapsedDays(Date d1, Date d2) {
        return elapsed(d1, d2, Calendar.DATE);
    }

    /**
     * Elapsed months based on current time
     *
     * @param date Date
     *
     * @return int number of months    */
    public static int getElapsedMonths(Date date) {
        return elapsed(date, Calendar.MONTH);
    }

    /**
     * Elapsed months based on two Date objects
     * @param d1 Date
     * @param d2 Date
     *
     * @return int number of months    */
    public static int getElapsedMonths(Date d1, Date d2) {
        return elapsed(d1, d2, Calendar.MONTH);
    }

    /**
     * Elapsed years based on current time
     *
     * @param date Date
     *
     * @return int number of years    */
    public static int getElapsedYears(Date date) {
        return elapsed(date, Calendar.YEAR);
    }

    /**
     * Elapsed years based on two Date objects
     *
     * @param d1 Date
     * @param d2 Date
     *
     * @return int number of years    */
    public static int getElapsedYears(Date d1, Date d2) {
        return elapsed(d1, d2, Calendar.YEAR);
    }

    /**
     * All elaspsed types
     *
     * @param g1 GregorianCalendar
     * @param g2 GregorianCalendar
     * @param type int (Calendar.FIELD_NAME)
     *
     * @return int number of elapsed "type"     */
    private static int elapsed(GregorianCalendar g1, GregorianCalendar g2, int type) {
        GregorianCalendar gc1, gc2;
        int elapsed = 0;
        // Create copies since we will be clearing/adding
        if (g2.after(g1)) {
            gc2 = (GregorianCalendar) g2.clone();
            gc1 = (GregorianCalendar) g1.clone();
        } else  {
            gc2 = (GregorianCalendar) g1.clone();
            gc1 = (GregorianCalendar) g2.clone();
        }
        if (type == Calendar.MONTH || type == Calendar.YEAR) {
            gc1.clear(Calendar.DATE);
            gc2.clear(Calendar.DATE);
        }
        if (type == Calendar.YEAR) {
            gc1.clear(Calendar.MONTH);
            gc2.clear(Calendar.MONTH);
        }
        while (gc1.before(gc2)) {
            gc1.add(type, 1);
            elapsed++;
        }
        return elapsed;
     }

    /**
     * All elaspsed types based on date and current Date
     * @param date Date
     * @param type int (Calendar.FIELD_NAME)
     *
     * @return int number of elapsed "type"     */
    private static int elapsed(Date date, int type) {
        return elapsed(date, new Date(), type);
    }

    /**
     *  All elaspsed types
     *
     * @param d1 Date
     * @param d2 Date
     * @param type int (Calendar.FIELD_NAME)
     *
     * @return int number of elapsed "type"     */
    private static int elapsed(Date d1, Date d2, int type) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d1);
        GregorianCalendar g1 = new GregorianCalendar( cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE) );
        cal.setTime(d2);
        GregorianCalendar g2 = new GregorianCalendar( cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE));
        return elapsed(g1, g2, type);
    }

    /*
    //
    // Calculates the number of days between two calendar days in a manner
    // which is independent of the Calendar type used.
    //
    // @param d1    The first date.
    // @param d2    The second date.
    //
    // @return      The number of days between the two dates.  Zero is
    //              returned if the dates are the same, one if the dates are
    //              adjacent, etc.  The order of the dates
    //              does not matter, the value returned is always >= 0.
    //              If Calendar types of d1 and d2
    //              are different, the result may not be accurate.
    //
     public static int getDaysBetween (java.util.Calendar d1, java.util.Calendar d2) {
        if (d1.after(d2)) {  // swap dates so that d1 is start and d2 is end
            java.util.Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        int days = d2.get(java.util.Calendar.DAY_OF_YEAR) -
                   d1.get(java.util.Calendar.DAY_OF_YEAR);
        int y2 = d2.get(java.util.Calendar.YEAR);
        if (d1.get(java.util.Calendar.YEAR) != y2) {
            d1 = (java.util.Calendar) d1.clone();
            do {
                days += d1.getActualMaximum(java.util.Calendar.DAY_OF_YEAR);
                d1.add(java.util.Calendar.YEAR, 1);
            } while (d1.get(java.util.Calendar.YEAR) != y2);
        }
        return days;
    } // getDaysBetween()
    */


    public static ArrayList getYearList()
	{
        int startYear = 2005;
        int endYear = 2025;

		ArrayList yearList = new ArrayList();
		for ( int i = startYear ; i < endYear; i++ )
		{
			yearList.add ( new LabelValueBean( ""+i, ""+i ) );
		}
		return yearList;
	}

    public static ArrayList loadQuarterListWithAll()
    {
        int start_qtr = 1;
        int end_qtr = 4;

        ArrayList quatersList = new ArrayList ();
        for ( int qtr = start_qtr; qtr <= end_qtr; qtr++ )
        {
            quatersList.add ( new LabelValueBean ( "Qtr " + qtr, qtr + "") );
        }
        quatersList.add( new LabelValueBean ( "All", "All") );

        return quatersList;
    }

    public static ArrayList loadQuarterList()
    {
        int start_qtr = 1;
        int end_qtr = 4;

        ArrayList quatersList = new ArrayList ();
        for ( int qtr = start_qtr; qtr <= end_qtr; qtr++ )
        {
            quatersList.add ( new LabelValueBean ( "Qtr " + qtr, qtr + "") );
        }

        return quatersList;
    }


    public static String getCurrentQuarter()
    {
        String qtr = "1";
        Calendar c = Calendar.getInstance();
        int month = c.get( Calendar.MONTH );

        if( month > 8 )
        {
            qtr = "4";
        }
        else if( month > 5 )
        {
            qtr = "3";
        }
        else if( month > 2 )
        {
            qtr = "2";
        }
        else
        {
            qtr = "1";
        }

        return qtr;
    }
    
    public static ArrayList loadHours()
    {
    	ArrayList hoursList = new ArrayList();
        for(int i= 1; i <= 12; i++)
        {
            hoursList.add(new org.apache.struts.util.LabelValueBean( i + "", i + ""  ));
        }
    	
    	return hoursList;
    }
 
    public static ArrayList loadMinutes()
    {
    	ArrayList minutesList = new ArrayList();
        String minutes = null;
        for(int i= 0; i <= 59; i++)
        {
            if ( ( i >= 0 ) && ( i <= 9 ) )
            {
                minutes = "0" + i;
            }
            else
            {
                minutes = i + "";
            }
            minutesList.add(new org.apache.struts.util.LabelValueBean( minutes, minutes ) );
        }
    	return minutesList;
    } 
    
    public static ArrayList loadAmPm()
    {
        ArrayList am_pmList = new ArrayList();
        am_pmList.add(new org.apache.struts.util.LabelValueBean("AM", java.util.Calendar.AM + ""));
        am_pmList.add(new org.apache.struts.util.LabelValueBean("PM", java.util.Calendar.PM + ""));
        
        return am_pmList;
    }

   /**
    * refer for dateformats.
    *  http://javatechniques.com/blog/dateformat-and-simpledateformat-examples/
   */
    public static String formatDate ( Date date, String dateFormat )
    {
        if(date == null)
            return null;

        if( dateFormat == null || dateFormat.trim().length() == 0 )
            dateFormat= "MM/dd/yyyy";

        SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);

        return formatter.format(date);
    }
    public static String getTimeStamp()
    {
        return formatDate( new Date(), "MMddyyHHmmss" );
    }
     
    public static String getFormattedTimeStamp()
    {
        return formatDate( new Date(), "MM-dd-yyyy-HH-mm-ss-SSS" );
    }
     /**
     * returns the String array representing the month names
     * @return
     */
    public static String[] getMonthsArray()
    {
        String months[] = { "January", "February", "March","April","May","June","July","August","September","October","November","December" };
        return months;
    }
     /**
     * returns the monts arrayList containing the labelvaluebean objects.<br>
     * The month value will be starts from one.
     * @return
     */
    public static ArrayList getMonthsList ( )
    {
        ArrayList monthsList            = new ArrayList();
        LabelValueBean labelValueBean   = null;
        String months[] = getMonthsArray();
        for ( int i=0; i < months.length; i++ )
        {
            labelValueBean = new LabelValueBean( months[i], Integer.toString(i+1) );
            monthsList.add ( labelValueBean );
        }
        return monthsList;
    }

     /**
      * Month Starts from 1
      * @return
      */
    public static int getCurrentMonth(Calendar calendar)
    {
        return calendar.get( Calendar.MONTH ) + 1;
    }
    public static int getCurrentYear( Calendar calendar )
    {
        return calendar.get( Calendar.YEAR );
    }
    public static int  getCurrentDay(Calendar calendar)
    {
        return calendar.get( Calendar.DAY_OF_MONTH );
    }
    public static int getCurrentHour(Calendar calendar)
    {
        return calendar.get( Calendar.HOUR_OF_DAY );
    }
    public static int getCurrentMinute(Calendar calendar)
    {
        return calendar.get( Calendar.MINUTE );
    }
    public static int  getCurrentSecond(Calendar calendar)
    {
        return calendar.get( Calendar.SECOND );
    }
    public static int  getCurrentMilliSecond(Calendar calendar)
    {
        return calendar.get( Calendar.MILLISECOND );
    }

    /**
      * Month Starts from 1
      * @return
      */
    public static int getCurrentMonth()
    {
        Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.MONTH ) + 1;
    }
    public static int getCurrentYear()
    {
        Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.YEAR );
    }
    public static int  getCurrentDay()
    {
        Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.DAY_OF_MONTH );
    }
    public static int getCurrentHour()
    {
        Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.HOUR_OF_DAY );
    }
     public static int getCurrent12Hour()
    {
        Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.HOUR );
    }
    public static int getCurrentMinute()
    {   Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.MINUTE );
    }
    public static int  getCurrentSecond()
    {    Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.SECOND );
    }
    public static int  getCurrentMilliSecond()
    {    Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.MILLISECOND );
    }
    public static int getCurrentAmPm()
     {
        Calendar cal = Calendar.getInstance();
        return cal.get( Calendar.AM_PM );
     }

    /**
    *
    * @return returns the current quarter number(Starts from one).
    */
    public static int getCurrentQtrNo( )
    {
        int qtrNo = 1;
        Calendar c = Calendar.getInstance();
        int month = c.get( Calendar.MONTH );

        if( month > 8 )
        {
            qtrNo = 4;
        }
        else if( month > 5 )
        {
            qtrNo = 3;
        }
        else if( month > 2 )
        {
            qtrNo = 2;
        }
        else
        {
            qtrNo = 1;
        }
        return qtrNo;
    }
      /**
      *
      * @param month month number starts from zero.
      * @return
      */
    public static String getShortMonthName( int month )
    {
        String months[] = { "Jan", "Feb", "Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };

        if ( month < months.length )
            return months[month];

        return null;
    }

    public static int getMonthNoByName( String month )
    {
        String months[] = { "Jan", "Feb", "Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
        int monthNo = -1;
        for(int i=0; i<months.length; i++)
        {
            if(month.startsWith(months[i]) )
            {   monthNo = i;
                break;
            }
        }
        return  monthNo;
        /*if (month.startsWith("Jan") )
        {
            return 0;
        }
        else if (month.startsWith( "Feb") )
        {

        }
        else if (month.startsWith( "Mar") )
        {

        } else if (month.startsWith("Apr") )
        {
        }
        else if (month.startsWith("May") )
        {
        }
        else if (month.startsWith("Jun") )
        {
        }
        else if (month.startsWith("Jul") )
        {
        }
        else if (month.startsWith("Aug") )
        {
        }
        else if (month.startsWith("Sep") )
        {
        }
        else if (month.startsWith("Oct") )
        {
        }
        else if (month.startsWith("Nov") )
        {
        }
        else if (month.startsWith("Dec") )
        {

        }
        else
        {
           return -1;
        }*/
    }

     public static String getPreviousDate(int days)
     {
        return getPreviousDate( days, "MM/dd/yyyy");

     }
     public static String getPreviousDate(int days, String format)
     {
         Calendar cal = Calendar.getInstance();

         cal.add(Calendar.DATE, -days);

         return formatDate( cal.getTime(), format );
     }
     public static String getNextDate(int days)
     {
        return getNextDate( days, "MM/dd/yyyy");
     }
     public static String getNextDate(int days, String format)
     {
         Calendar cal = Calendar.getInstance();

         cal.add(Calendar.DATE, days);

         return formatDate( cal.getTime(), format );
     }
     public static String getCurrentDate()
     {
         return getCurrentDate("MM/dd/yyyy");
     }
     public static String getCurrentDate(String format)
     {
         return formatDate( new Date(), format);
     }

     public static ArrayList getDefaultDateCodeList( boolean isOtherDatecodeRequierd)
     {
          ArrayList dateCodeList = new ArrayList();
        int currentwk1; int currentwk2; int currentwk3;
        String yearAsDigit1; String yearAsDigit2; String yearAsDigit3;
        WorkWeek wk = WorkWeek.getCurrentWorkWeekInstance();
        currentwk1 = wk.getCurrentWWNumber();
        yearAsDigit1  = (wk.getWorkWeekYear()+"").substring(2);
        if ( currentwk1 == 1 )
        {
            Date dt =  wk.getCurrentWWStartDate();
            Calendar previousWkDate = Calendar.getInstance();
            previousWkDate.setTime( dt );
            previousWkDate.add( Calendar.DATE, -3 );
            WorkWeek prevWk = WorkWeek.getWorkWeekInstance( previousWkDate.getTime() );
            currentwk2 = prevWk.getCurrentWWNumber();
            currentwk3 = currentwk2 -1;
            yearAsDigit2  = (prevWk.getWorkWeekYear()+"").substring(2);
            yearAsDigit3 = yearAsDigit2;
        }
        else if ( currentwk1 == 2 )
        {
            currentwk2 = currentwk1 -1;
            yearAsDigit2  = yearAsDigit1;

            Date dt =  wk.getCurrentWWStartDate();
            Calendar previousWkDate = Calendar.getInstance();
            previousWkDate.setTime( dt );
            previousWkDate.add( Calendar.DATE, -10 );
            WorkWeek prevWk = WorkWeek.getWorkWeekInstance( previousWkDate.getTime() );
            currentwk3 = prevWk.getCurrentWWNumber();
            yearAsDigit3  = (prevWk.getWorkWeekYear()+"").substring(2);

        }
        else
        {
            currentwk2 = currentwk1 -1;
            currentwk3 = currentwk1 -2;
            yearAsDigit2  = yearAsDigit1;
            yearAsDigit3 = yearAsDigit1;
        }

        dateCodeList.add( new LabelValueBean(yearAsDigit3 + (currentwk3<10?"0"+currentwk3 : ""+currentwk3), yearAsDigit3 + (currentwk3<10?"0"+currentwk3 : ""+currentwk3) ) );
        dateCodeList.add( new LabelValueBean(yearAsDigit2 + (currentwk2<10?"0"+currentwk2 : ""+currentwk2), yearAsDigit2 + (currentwk2<10?"0"+currentwk2 : ""+currentwk2) ) );
        dateCodeList.add( new LabelValueBean(yearAsDigit1 + (currentwk1<10?"0"+currentwk1 : ""+currentwk1), yearAsDigit1 + (currentwk1<10?"0"+currentwk1 : ""+currentwk1) ) );
        if ( isOtherDatecodeRequierd)
        {
            dateCodeList.add( new LabelValueBean("--other--", "0") );
        }

         return dateCodeList;
     }
     
     /**
      * @param month
      * Month starts from 1
      * @return
      * returns the quarter no of the given month.<br>
      * quarter no starts form 1.
      */
    public static int getQuarterOfMonth ( int month )
    {
        int qtr = 1;
        if( month > 9 )
        {
            qtr = 4;
        }
        else if( month > 6 )
        {
            qtr = 3;
        }
        else if( month > 3 )
        {
            qtr = 2;
        }
        else
        {
            qtr = 1;
        }

        return qtr;
    }
    
    /**
     * returns the starting month no of the given qtr.
     * month no starts from one.
     * @param qtrNo starts from one.
     * @return
     */
    public static int getStartMonthOfQtr ( int qtrNo )
    {
        if ( qtrNo == 1 )
        {
            return 1;
        }
        else if ( qtrNo == 2 )
        {
            return 4;
        }
        else if ( qtrNo == 3 )
        {
            return 7;
        }
        else if ( qtrNo == 4 )
        {
            return 10;
        }
        throw new IllegalArgumentException( "Quarter number should be in 1 to 4" );
    }
    public static int getEndMonthOfQtr ( int qtrNo )
    {
        if ( qtrNo == 1 )
        {
            return 3;
        }
        else if ( qtrNo == 2 )
        {
            return 6;
        }
        else if ( qtrNo == 3 )
        {
            return 9;
        }
        else if ( qtrNo == 4 )
        {
            return 12;
        }
        throw new IllegalArgumentException( "Quarter number should be in 1 to 4" );
    }
 }


